<!--
 * @Author: lide1202@hotmail.com
 * @Date: 2021-3-13 11:04:24
 * @Last Modified by:   lide1202@hotmail.com
 * @Last Modified time: 2021-3-13 11:04:24
 !-->
<template>
  <div>
    <avue-draggable
      :width="widgetsWidth"
      :height="widgetsHeight"
      :left="widgetsLeft"
      :top="widgetsTop"
      ref="draggable"
      :index="index"
      :style="{ zIndex: widgetsZIndex }"
      :scale="designerComponent.stepScale"
      :step="designerComponent.stepScale"
      v-show="widgetsDisplay"
      :disabled="widgetsDisabled"
      @focus="handlefocus"
      @blur="handleBlur"
      @move="handleMove"
      @over="handleOver"
    >
      <template slot="menu">
        <div>
          宽: {{ value.position.width }}<br />高:{{ value.position.height
          }}<br />层级:{{ value.position.zIndex }}
        </div>
      </template>
      <component :is="type" :value="value" />
    </avue-draggable>
  </div>
</template>

<script>
import widgetText from "./widgetText.vue";
import widgetImage from "./widgetImage.vue";
import widgetBarStackChart from "./widgetBarStackChart";
import widgetLineStackChart from "./widgetLineStackChart";
import WidgetPiechart from "./widgetPiechart.vue";
import widgetMap from "./widgetMap.vue";
import widgetTable from "./widgetTable.vue";
import widgetList from "./widgetList";
// import WidgetZuhe from "./widgetZuhe";
export default {
  name: "Widget",
  inject: ["designerComponent"],
  components: {
    widgetText,
    widgetImage,
    widgetBarStackChart,
    widgetLineStackChart,
    WidgetPiechart,
    widgetMap,
    widgetTable,
    widgetList,
    // WidgetZuhe
  },
  model: {
    prop: "value",
    event: "input",
  },
  props: {
    index: Number, // 当前组件，在工作区变量widgetInWorkbench中的索引
    type: String,
    bigscreen: Object,
    value: {
      type: [Object],
      default: () => {},
    },
    // widgetComponent: Array
  },
  data() {
    return {
      data: {
        setup: {},
        data: {},
        position: {},
      },
      focusPosition: "",
      left: "",
      top: "",
      otherObj: [],
      otherWidgers: [],
      active: false,
    };
  },
  computed: {
    widgetsWidth() {
      return this.value.position.width;
    },
    widgetsHeight() {
      return this.value.position.height;
    },
    widgetsLeft() {
      return this.value.position.left;
    },
    widgetsTop() {
      return this.value.position.top;
    },
    widgetsZIndex() {
      return this.value.position.zIndex || 0;
    },
    widgetsDisplay() {
      return this.value.setup.display;
    },
    widgetsDisabled() {
      return this.value.setup.disabled;
    },
  },
  mounted() {},
  methods: {
    // 组件移动
    handleMove({ index, left, top, width, height }) {
      // 取出所有组件
      const widgets = this.designerComponent.widgets;
      // 如果拖拽当前项不包含在激活项中, 取消所有高亮，高亮当前项
      if (!this.designerComponent.widgetIndex.includes(widgets[index].id)) {
        this.designerComponent.widgetIndex = [widgets[index].id];
        this.designerComponent.widgetComponent = [widgets[index]];
        for (let i = 0; i < widgets.length; i++) {
          this.designerComponent.$refs.widgets[i].$refs.draggable.setActive(
            false
          );
        }

        this.$refs.draggable.setActive(true);
        return;
      }
      // 计算拖拽的当前项偏移位置
      const xMove = this.designerComponent.getFixed(left - this.left);
      const yMove = this.designerComponent.getFixed(top - this.top);
      // 取出除了自己本身的激活组件
      const otherWidget = this.designerComponent.widgetComponent.filter(
        (item) => item.id !== widgets[index].id
      );
      // 除了自己其他组件同步修改距离
      otherWidget.map((item, index) => {
        item.value.position.left =
          this.otherObj.filter((ite) => ite.id === item.id)[0]?.left + xMove;
        item.value.position.top =
          this.otherObj.filter((ite) => ite.id === item.id)[0]?.top + yMove;
      });
    },
    // 组件聚焦
    handlefocus({ index, left, top, width, height, event }) {
      // 左键点击设为高亮
      if (event.which === 1) {
        this.active = true;
      }
      // 保存初始位置，判断是否移动了
      this.focusPosition = left + top;
      // 保存当前激活项的位置
      this.left = left;
      this.top = top;
      // 取出所有组件
      const widgets = this.designerComponent.widgets;
      // 取出除了自己本身的激活组件
      const otherWidget = this.designerComponent.widgetComponent.filter(
        (item) => item.id !== widgets[index].id
      );
      this.otherWidgers = [];
      this.otherObj = [];
      // 存储除了自己本身的激活组件的初始位置，用于在移动的时候计算偏移距离
      otherWidget.map((item) => {
        this.otherWidgers.push(item);
        this.otherObj.push({
          id: item.id,
          left: item.value.position.left,
          top: item.value.position.top,
        });
      });
    },
    // 组件失去焦点
    handleBlur({ index, left, top, width, height, event }) {
      // console.log("event", event);
      // 通过index取出id
      const widgets = this.designerComponent.widgets;
      // 如果是右键操作
      if (event.which === 3) {
        // 如果当前项是未选中的,选中当前项，取消其他选项
        if (!this.active) {
          this.designerComponent.widgetIndex = [widgets[index].id];
          this.designerComponent.widgetComponent = [widgets[index]];
          for (let i = 0; i < widgets.length; i++) {
            this.designerComponent.$refs.widgets[i].$refs.draggable.setActive(
              false
            );
          }

          this.$refs.draggable.setActive(true);
        }
        return;
      }

      if (this.focusPosition === left + top) {
        // 如果按住了ctrl点击,多选
        this.designerComponent.layerClick(widgets[index], {
          index,
          left,
          top,
          width,
          height,
        });
      } else {
        // 移动第三个参数设置为true
        this.designerComponent.layerClick(
          widgets[index],
          { index, left, top, width, height },
          true
        );
      }
    },
    handleOver({ index, left, top, width, height }) {
      // 存储鼠标滑过时是高亮还是不高亮
      this.active = this.$refs.draggable.active;
    },
  },
};
</script>

<style scoped lang="less">
.vue-draggalbe {
  position: absolute;
}
.widget-active {
  cursor: move;
  border: 1px dashed #09f;
  background-color: rgba(115, 170, 229, 0.5);
}
.avue-draggable {
  padding: 0 !important;
}
/deep/.avue-draggable__menu {
  font-size: 10px;
  padding: 4px 6px;
  background: rgba(70, 70, 70, 0.6);
  border-radius: 4px;
  top: initial;
  left: initial;
  bottom: -8px;
  right: -90px;
  text-align: left;
}
</style>
